package org.example.exception;

import org.example.domain.BaseCodeEnum;
import org.example.domain.ICodeEnum;
import lombok.Getter;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: sql
 * @date: 2024/6/7
 * @Description: 处理业务逻辑时，进行抛出的异常。
 * @version: 1.0
 */
@Getter
public class BusinessException extends RuntimeException {

    /**
     * 错误代码
     */
    protected final String code;

    /**
     * 错误提示
     */
    protected final String msg;

    /**
     * 扩展信息
     */
    protected final Object extend;

    /**
     * 过滤不需要打印的堆栈信息
     *
     * @return
     */
    protected List<StackTraceElement> filterStackTrace() {
        StackTraceElement[] originalStack = super.getStackTrace();
        List<StackTraceElement> filteredList = new ArrayList<>();

        for (StackTraceElement element : originalStack) {
            // 需要打印的包名 "com.pactera"
            if (element.getClassName().startsWith("com.pactera")) {
                filteredList.add(element);
            }
        }
        return filteredList;
    }

    @Override
    public StackTraceElement[] getStackTrace() {
        List<StackTraceElement> stackTraceElements = this.filterStackTrace();
        if (CollectionUtils.isEmpty(stackTraceElements)) {
            return super.getStackTrace();
        }
        // 返回过滤后的堆栈信息
        return stackTraceElements.toArray(new StackTraceElement[0]);
    }

    public BusinessException(ICodeEnum codeEnum) {
        this(codeEnum, null);
    }

    public BusinessException(ICodeEnum codeEnum, Object extend) {
        this(codeEnum.getCode(), codeEnum.getMsg(), extend);
    }

    public BusinessException(String msg) {
        this(BaseCodeEnum.SERVICE_EXCEPTION.getCode(), msg);
    }

    public BusinessException(String code, String msg) {
        this(code, msg, null);
    }

    public BusinessException(String msg, Object extend) {
        this(BaseCodeEnum.SERVICE_EXCEPTION.getCode(), msg, extend);
    }

    public BusinessException(String code, String msg, Object extend) {
        super(String.format("[%s] %s", code, msg));
        this.code = code;
        this.msg = msg;
        this.extend = extend;
    }

}
